home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Surfer: Getting Started
/
Internet Surfer - Getting Started (Wayzata Technology)(7231)(1995).bin
/
pc
/
mac
/
bonus
/
peter_le
/
finger-1
/
fingerd
/
fingerd.p
Wrap
Text File
|
1992-02-24
|
6KB
|
242 lines
{$I-}
program Fingerd;
{ This code is part of the Finger/Fingerd source code, written in THINK Pascal 4 }
{ Copyright 1991-1992 Peter N Lewis }
{ If you use this code, you must give me credit in your about box and documentation }
uses
AppleTalk, PPCToolbox, Processes, EPPC, Notification, AppleEvents, {}
TCPTypes, TCPStuff, FingerDaemon, PrefsGlobals, Folders, MyUtilities, MyPreferences;
const
strh_id = 128;
prefname_index = 1;
pref_launch_str = 2;
quitnow_index = 3;
lf = 10;
daemons_max = 10;
var
quitNow: boolean;
function GotRequiredParams (theAppleEvent: AppleEvent): OSErr; { <aevt> }
var
typeCode: DescType;
actualSize: Size;
err: OSErr;
begin
err := AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, typeCode, nil, 0, actualSize); { nil ok: need only function result }
if err = errAEDescNotFound then { we got all the required params: all is ok }
GotRequiredParams := noErr
else if err = noErr then
GotRequiredParams := errAEEventNotHandled
else
GotRequiredParams := err;
end; { GotRequiredParams }
function HandleQUIT (theAppleEvent, reply: AppleEvent; quitp: ptr): OSErr; { <aevt> }
var
oe: OSErr;
errStr: Str255;
willQuit: Boolean; { did the user allow the quit or cancel }
begin
{ We don't expect any params at all, but check in case the client requires any }
oe := GotRequiredParams(theAppleEvent);
quitNow := true;
if reply.dataHandle <> nil then { a reply is sought }
begin
if oe = noErr then
errStr := 'OK'
else
errStr := 'user cancelled quit';
oe := AEPutParamPtr(reply, 'errs', 'TEXT', Ptr(@errStr[1]), length(errStr));
end;
HandleQUIT := oe;
end;
function OpenPrefFile (name: str63): integer;
var
vrn: integer;
dirID: longint;
oe: OSErr;
gv: longInt;
fil: integer;
begin
oe := Gestalt(gestaltFindFolderAttr, gv);
if (oe = noErr) & (BTST(gv, gestaltFindFolderPresent)) & (FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, vrn, dirID) = NoErr) then
fil := HOpenResFile(vrn, dirID, name, fsRdPerm)
else begin
fil := OpenResFile(concat(':Preferences:', name));
if fil <> -1 then
fil := OpenResFile(name);
end;
OpenPrefFile := fil;
end;
procedure HandleEvents (speed: integer);
var
dummy: boolean;
er: eventRecord;
oe: OSErr;
begin
dummy := WaitNextEvent(everyEvent, er, speed, nil);
if er.what = kHighLevelEvent then
if has_AppleEvents then
oe := AEProcessAppleEvent(er);
end;
function StackPtr: longInt;
inline
$2E8F;
var
tcpc: array[1..daemons_max] of TCPConnectionPtr;
t: TCPStateType;
buffer: str255;
temp: longInt;
finger_port: integer;
readPos: longInt;
f: longInt;
gotlf: boolean;
i: integer;
oe: OSErr;
appllimitP: ^longInt;
remoteIP: longInt;
quitNowStr: str15;
pref_name: str63;
defrefnum: integer;
gv: longInt;
max_daemons, this_daemon: integer;
finished: boolean;
prefs_fs: FSSpec;
prefs_rn: integer;
begin
applLimitP := POINTER($130);
applLimitP^ := StackPtr - 5000;
{ SetApplLimit(ptr(StackPtr - 5000));}
MaxApplZone;
MoreMasters;
GetIndString(buffer, strh_id, quitnow_index);
quitNowStr := buffer;
GetIndString(buffer, strh_id, prefname_index);
pref_name := buffer;
GetIndString(buffer, fingerd_strh, fingerd_port_index);
StringToNum(buffer, temp);
{$PUSH}
{$R-}
finger_port := temp;
{$R-}
quitNow := false;
oe := Gestalt(gestaltAppleEventsAttr, gv);
has_AppleEvents := (oe = noErr) and (gv = 1);
if has_AppleEvents then
oe := AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, @HandleQUIT, 0, false);
for i := 1 to 5 do
HandleEvents(5);
oe := TCPInit;
if oe = noErr then begin
oe := Gestalt('mtcp', gv);
if (oe = noErr) and (gv >= 1) then begin
GetIndString(buffer, fingerd_strh, daemons_max_index);
StringToNum(buffer, gv);
if gv > daemons_max then
max_daemons := daemons_max
else if gv < 1 then
max_daemons := 1
else
max_daemons := gv;
end
else
max_daemons := 1;
InitDaemon;
for i := 1 to max_daemons do
tcpc[i] := nil;
for i := 1 to max_daemons do begin
oe := TCPPassiveOpen(tcpc[i], finger_port, 0, 0, nil);
if oe <> noErr then begin
quitNow := true;
tcpc[i] := nil;
leave;
end;
end;
while not quitNow do begin
IdleFingers;
this_daemon := -1;
while (this_daemon < 0) and not quitNow do begin
HandleEvents(15);
IdleFingers;
for i := 1 to max_daemons do
if TCPState(tcpc[i]) <> T_Listening then
this_daemon := i;
end;
if not quitNow then begin
f := TickCount;
readPos := 0;
repeat
HandleEvents(5);
IdleFingers;
{$PUSH}
{$R-}
oe := TCPReceiveUpTo(tcpc[this_daemon], lf, 1, @buffer[1], 255, readPos, gotlf);
{$POP}
until (oe <> noErr) or (readPos = 255) or gotlf or (TickCount > f + 60 * 60) or quitNow;
if gotlf then begin
{$PUSH}
{$R-}
buffer[0] := chr(readPos - 2);
{$POP}
quitNow := (quitNowStr <> '') and (quitNowStr = buffer);
IdleFingers;
oe := SysEnvirons(1, sysenv);
oe := SetVol(nil, sysenv.sysVRefNum);
GetPrefsFSSpec(prefs_fs);
prefs_rn := OpenPrefsFile(prefs_fs);
GetPrefs(prefs);
if prefs.plan_dirID <> -1 then
SendPlan(tcpc[this_daemon], prefs.plan_vrn, prefs.plan_dirID, prefs.plan_name, buffer)
else
SendPlan(tcpc[this_daemon], 0, 0, 'Plan', buffer);
if prefs_rn <> -1 then
CloseResFile(prefs_rn);
end;
oe := TCPFlush(tcpc[this_daemon]);
oe := TCPClose(tcpc[this_daemon], nil);
t := TCPState(tcpc[this_daemon]);
f := TickCount;
while (t <> T_Closed) and (TickCount < f + 60 * 60) do begin
IdleFingers;
HandleEvents(5);
t := TCPState(tcpc[this_daemon]);
end;
oe := TCPRelease(tcpc[this_daemon]);
if not quitNow then begin
oe := TCPPassiveOpen(tcpc[this_daemon], finger_port, 0, 0, nil);
if oe <> noErr then
leave;
end
else
tcpc[this_daemon] := nil;
end;
end;
for i := 1 to max_daemons do
if tcpc[i] <> nil then
oe := TCPClose(tcpc[i], nil);
f := TickCount;
finished := false;
while not finished and (TickCount < f + 60 * 60) do begin
HandleEvents(5);
finished := true;
for i := 1 to max_daemons do
if tcpc[i] <> nil then
if TCPState(tcpc[i]) <> T_Closed then
finished := false
else begin
oe := TCPRelease(tcpc[i]);
tcpc[i] := nil;
end;
end;
FinishDaemon;
TCPFinish;
end;
end.